Re: Xwindows security?

Bennett Todd (bet@std.sbi.com)
Mon, 9 Jan 1995 14:27:17 -0500 (EST)

>However, this is not really a problem.  X contains authorization
>mechanisms [....]  As is so often the case, the way to attack this problem
>is by educating people, thus making them understand why they want to be
>careful and what mechanisms are available to allow them to do so, rather
>than imposing technical restrictions that are easy to get around and, since
>they don't teach anyone _why_ they're there, just incite people to do so.

I don't really entirely disagree here, but I think "educating people" is
only part of the process of convincing management to allow you to make a
change (and demo programs like the recently-posted "xkey" are great for this
purpose); the actual change I think is best made by automating it. Don't try
to convince all your users to set up xauth(1); that's a hideous job, made
vastly harder than it should be by the cryptic documentation, and the lack
of a secure standard cookie generator. Instead fix the standard startup
script that users invoke, so that they begin running with proper
authentication. There's still some education involved; you've gotta also
develop suitable tools for helping them pass cookies around wherever they
need to, and teach them how to use them; but I think the bulk of the job
lies in automating the setup and use of Xauthority so it's no additional
bother for users.

-Bennett
bet@sbi.com

P.S. For completeness, here's my current cookie generator. I invoke it as
"randstuff 32 HEX" to generate a key suitable for MIT-MAGIC-COOKIE-1.

#!/usr/local/bin/perl

# This is a joint development project. People have contributed tips from all
# over; please forgive me (and let me know!) if you aren't mentioned below.
# But the basic concept came from Larry Wall, the first major attempt at an
# implementation came from Bennett Todd, then Larry Wall came back with more
# bugfixes and enhancements than there were actual lines of code. Since then
# other people have contributed tweaks and enhancements. Additional helpful
# ``noise'' commands have been contributed by Brian Ward.

($progname=$0)=~s#.*/##;
$syntax="syntax: $progname [-n] [len [printable|all|hex|HEX]]\n";
require 'getopts.pl';
&Getopts('n') || die $syntax;

defined($max = shift)      || ($max = 8);
defined($alphabet = shift) || ($alphabet = 'printable');
($#ARGV == -1)             || die $syntax;

domain: {
	$_ = $alphabet;
	/^printable$/ && do { $chars = pack("C*", (32 .. 126)); last domain; };
	/^all$/ && do       { $chars = pack("C*", ( 0 .. 255)); last domain; };
	/^hex$/ && do       { $chars = "0123456789abcdef";      last domain; };
	/^HEX$/ && do       { $chars = "0123456789ABCDEF";      last domain; };
	die $syntax;
};

@chars = split('', $chars);

@randstring = split('', &randbits($max));

foreach $i (@randstring) {
	print $chars[ord($i) % $#chars];
}

print "\n" unless $opt_n;

exit 0;

sub randbits {
	local($nbytes) = @_;
	local(*_, $noise, $buf, $limit, $discard, $newlen);

	# Here's the big non-portability. This command works really well on
	# Sun workstations running SunOS; on other platforms, root around for
	# commands that report lots of detailed OS internals state, plus a
	# compressor or other program to smear the bits about.
	$noise = '(ps -agxlww;pstat -afipSsT;free;cat /proc/net/dev)2>/dev/null|compress';

	# Run the noise command; in case it croaks, slap on whatever other state we
	# can conveniently (portably) find.
	$buf = `$noise` . $$ . getppid() . time . join('', %ENV);

	# Gotta have enough bits for at least one good fold.
	$limit = int(length($buf)/2);
	die "Insufficient random state; try less than $limit\n" if $nbytes > $limit;

	# Get Perl to treat ^ as bit-string op
	$discard = vec($buf, 0, 8);

	# Now fold the noise down by repeated xor, halving the buffer until it's but
	# little bigger than xauth(1) wants.
	while (length($buf) >= $nbytes*2) {
		$newlen = int((length($buf) + 1) / 2);
		$buf = (substr($buf, 0, $newlen) ^ substr($buf, $newlen, $newlen));
	}

	# Final fold may turn in some nulls, but fits it exactly to $nbytes without
	# discarding any bits.
	substr($buf, 0, $nbytes) ^ substr($buf, $nbytes, $nbytes);
}